package cn.iocoder.yudao.module.ao.controller.admin.student;

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.util.ArrayList;
import java.io.IOException;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import com.alibaba.excel.EasyExcel;

import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.yudao.module.ao.controller.admin.student.vo.*;
import cn.iocoder.yudao.module.ao.dal.dataobject.student.StudentDO;
import cn.iocoder.yudao.module.ao.service.student.StudentService;

@Tag(name = "管理后台 - 学生信息")
@RestController
@RequestMapping("/ao/student")
@Validated
public class StudentController {

    @Resource
    private StudentService studentService;

    @PostMapping("/create")
    @Operation(summary = "创建学生信息")
    @PreAuthorize("@ss.hasPermission('ao:student:create')")
    public CommonResult<Long> createStudent(@Valid @RequestBody StudentSaveReqVO createReqVO) {
        return success(studentService.createStudent(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新学生信息")
    @PreAuthorize("@ss.hasPermission('ao:student:update')")
    public CommonResult<Boolean> updateStudent(@Valid @RequestBody StudentSaveReqVO updateReqVO) {
        studentService.updateStudent(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除学生信息")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('ao:student:delete')")
    public CommonResult<Boolean> deleteStudent(@RequestParam("id") Long id) {
        studentService.deleteStudent(id);
        return success(true);
    }

    @DeleteMapping("/delete-list")
    @Parameter(name = "ids", description = "编号", required = true)
    @Operation(summary = "批量删除学生信息")
                @PreAuthorize("@ss.hasPermission('ao:student:delete')")
    public CommonResult<Boolean> deleteStudentList(@RequestParam("ids") List<Long> ids) {
        studentService.deleteStudentListByIds(ids);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得学生信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('ao:student:query')")
    public CommonResult<StudentRespVO> getStudent(@RequestParam("id") Long id) {
        StudentDO student = studentService.getStudent(id);
        return success(BeanUtils.toBean(student, StudentRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得学生信息分页")
    @PreAuthorize("@ss.hasPermission('ao:student:query')")
    public CommonResult<PageResult<StudentRespVO>> getStudentPage(@Valid StudentPageReqVO pageReqVO) {
        PageResult<StudentDO> pageResult = studentService.getStudentPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, StudentRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出学生信息 Excel")
    @PreAuthorize("@ss.hasPermission('ao:student:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportStudentExcel(@Valid StudentPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<StudentDO> list = studentService.getStudentPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "学生信息.xls", "数据", StudentRespVO.class,
                        BeanUtils.toBean(list, StudentRespVO.class));
    }

    @GetMapping("/get-import-template")
    @Operation(summary = "获得学生信息导入模板")
    public void importStudentTemplate(HttpServletResponse response) throws IOException {
        // 手工创建导入模板的数据
        List<StudentImportExcelVO> list = Arrays.asList(
                StudentImportExcelVO.builder()
                        .serialNumber("1")
                        .name("张三")
                        .studentNo("2024001")
                        .idCard("440123199001011234")
                        .genderStr("男")
                        .school("某某技术学院")
                        .classInfo("计算机科学与技术1班")
                        .classTeacher("李老师")
                        .studentClass("计算机1班")
                        .studentNoSecond("2024001")
                        .guardianPhone("13800138001")
                        .studentPhone("13900139001")
                        .studentType("普通学生")
                        .status("在读")
                        .classAssignmentTime("2024-09-01")
                        .dataUpdate("2024-07-26")
                        .build()
        );
        // 输出
        ExcelUtils.write(response, "学生信息导入模板.xls", "学生信息", StudentImportExcelVO.class, list);
    }

    @PostMapping("/import")
    @Operation(summary = "导入学生信息")
    @Parameter(name = "file", description = "Excel 文件", required = true)
    @Parameter(name = "updateSupport", description = "是否支持更新，默认为 false", example = "true")
    public CommonResult<StudentImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
                                                         @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {

        System.out.println("=== 开始导入Excel文件 ===");
        System.out.println("文件名: " + file.getOriginalFilename());
        System.out.println("文件大小: " + String.format("%.2f KB", file.getSize() / 1024.0));

        // 读取原始数据
        List<Map<Integer, String>> rawData = EasyExcel.read(file.getInputStream()).doReadAllSync();
        System.out.println("总行数: " + rawData.size());

        // 手动创建StudentImportExcelVO列表
        List<StudentImportExcelVO> list = new ArrayList<>();

        // 跳过第一行（表头），从第二行开始处理数据
        for (int i = 1; i < rawData.size(); i++) {
            Map<Integer, String> row = rawData.get(i);
            StudentImportExcelVO student = new StudentImportExcelVO();

            // 根据您的Excel列顺序映射数据
            // 顺序号	姓名	学号	身份证号	性别	就读学校	班级	班主任	学籍班	学籍号	家庭电话	学生电话	学生类型	状态	分班时间	资料更新
            student.setSerialNumber(row.get(0));    // A列：顺序号
            student.setName(row.get(1));            // B列：姓名
            student.setStudentNo(row.get(2));       // C列：学号
            student.setIdCard(row.get(3));          // D列：身份证号
            student.setGenderStr(row.get(4));       // E列：性别
            student.setSchool(row.get(5));          // F列：就读学校
            student.setClassInfo(row.get(6));       // G列：班级
            student.setClassTeacher(row.get(7));    // H列：班主任
            student.setStudentClass(row.get(8));    // I列：学籍班
            student.setStudentNoSecond(row.get(9)); // J列：学籍号
            student.setGuardianPhone(row.get(10));  // K列：家庭电话
            student.setStudentPhone(row.get(11));   // L列：学生电话
            student.setStudentType(row.get(12));    // M列：学生类型
            student.setStatus(row.get(13));         // N列：状态
            student.setClassAssignmentTime(row.get(14)); // O列：分班时间
            student.setDataUpdate(row.get(15));     // P列：资料更新

            list.add(student);
        }

        System.out.println("解析完成，有效数据行数: " + list.size());

        // 打印前3条数据作为验证
        for (int i = 0; i < Math.min(3, list.size()); i++) {
            StudentImportExcelVO student = list.get(i);
            System.out.println(String.format("示例数据%d: 姓名=%s, 学号=%s, 性别=%s",
                i + 1, student.getName(), student.getStudentNo(), student.getGenderStr()));
        }

        return success(studentService.importStudentList(list, updateSupport));
    }

}